//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Log.print('service module: trapezi');

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Service.trapezi = {};

// Το service "trapezi.neo" καλείται για τη δημιουργία νέου τραπεζιού.

Service.trapezi.neo = function(nodereq) {
	if (nodereq.isvoli()) return;
	DB.connection().transaction(function(conn) {
		Service.trapezi.neo1(nodereq, conn);
	});
}

// Σε πρώτη φάση εισάγεται νέο τραπέζι στην database με τον δημιουργό του τραπεζιού
// στη θέση 1.

Service.trapezi.neo1 = function(nodereq, conn) {
	new Trapezi({
		pektis1: nodereq.login,
	}).trapeziRowAdd(conn,

	// Το τραπέζι εισήχθη κανονικά στην database και προχωρούμε στην επόμενη φάση.

	function(conn) {
		Service.trapezi.neo2(nodereq, conn, this);
	},

	// Απέτυχε η εισαγωγή του τραπεζιού στην database οπότε κάνουμε rollback και
	// τερματίζουμε τη διαδικασία αποστέλλοντας σχετικό μήνυμα λάθους.

	function(conn) {
		conn.rollback();
		nodereq.end('Απέτυχε η εισαγωγή νέου τραπεζιού στην database');
	});
}

// Στη φάση που ακολουθεί δημιουργείται αυτοπρόσκληση του δημιουργού και επιχειρείται
// εισαγωγή της πρόσκλησης στην database.

Service.trapezi.neo2 = function(nodereq, conn, trapezi) {
	new Prosklisi({
		apo: trapezi.pektisGet(1),
		trapezi: trapezi.kodikosGet(),
	}).prosklisiRowAdd(conn,

	// Η πρόσκληση εισήχθη κανονικά στην database και προχωρούμε στην επόμενη φάση.

	function(conn) {
		Service.trapezi.neo3(nodereq, conn, trapezi, this);
	},

	// Απέτυχε η εισαγωγή της αυτοπρόσκλησης στην database οπότε κάνουμε rollback και
	// τερματίζουμε τη διαδικασία αποστέλλοντας σχετικό μήνυμα λάθους.

	function(conn) {
		conn.rollback();
		nodereq.end('Απέτυχε η εισαγωγή αυτοπρόσκλησης στην database');
	});
}

// Έχουμε τελειώσει όλες τις διαδικασίες στις οποίες εμπλέκεται η database, επομένως
// κάνουμε commit την transaction, ενημερώνουμε το σκηνικό στον skiser και αποστέλλουμε
// κίνηση νέου τραπεζιού στους clients.

Service.trapezi.neo3 = function(nodereq, conn, trapezi, prosklisi) {
	var
	skiniko = nodereq.skinikoGet(),
	pektis = nodereq.loginGet(),
	sinedria = nodereq.sinedriaGet();

	conn.commit();
	nodereq.end();

	// Εντάσσουμε την αυτοπρόσκληση στο τραπέζι και εισάγουμε το τραπέζι
	// στο σκηνικό.

	skiniko.trapeziAdd(trapezi.prosklisiAdd(prosklisi));
	trapezi.tabloGet().replay();

	// Αν ο δημιουργός ήταν περιφερόμενος τον διαγράφουμε από τη λίστα των
	// περιφερομένων.

	skiniko.rebelosDelete(pektis);

	// Αν ο δημιουργός ήταν περιφερόμενος τον εντάσσουμε στο νέο τραπέζι.

	if (sinedria.isRebelos()) sinedria.setPektis(trapezi.kodikosGet(), 1);

	// Δημιουργούμε κίνηση νέου τραπεζιού με όλα τα απαραίτητα δεδομένα και
	// ενημερώνουμε τους clients.

	skiniko.kinisiAdd(new Kinisi('TR').set({
		t: trapezi.kodikos,
		p: trapezi.pektis1,
		l: prosklisi.kodikos,
	}));
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Service.trapezi.exodos = function(nodereq) {
	var skiniko = nodereq.skinikoGet(), pektis, trapezi, sinedria;

	if (nodereq.isvoli()) return;

	trapezi = nodereq.trapeziGet();
	if (!trapezi) return nodereq.error('Ακαθόριστο τραπέζι παίκτη');

	pektis = nodereq.loginGet();

	trapezi.
	theatisDelete(pektis).
	exodosPekti(pektis);

	sinedria = nodereq.sinedriaGet()
	sinedria.
	setRebelos().
	entopismos(skiniko);

	nodereq.end();
	skiniko.kinisiAdd(new Kinisi('EX').set({
		p: pektis,
	}));
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Service.trapezi.epilogi = function(nodereq) {
	var skiniko = nodereq.skinikoGet(), kodikos, trapezi, pektis, sinedria, trapeziPrev, thesi;

	if (nodereq.isvoli()) return;
	if (!nodereq.url.hasOwnProperty('trapezi')) return nodereq.error('Απροσδιόριστο τραπέζι');

	kodikos = nodereq.url.trapezi;
	trapeziPrev = nodereq.trapeziGet();
	if (trapeziPrev && (trapeziPrev.kodikosGet() == kodikos)) return nodereq.end();

	trapezi = skiniko.trapeziGet(kodikos);
	if (!trapezi) return nodereq.error('Ανυπόστατο τραπέζι');

	nodereq.end();

	pektis = nodereq.loginGet();
	sinedria = nodereq.sinedriaGet();

	skiniko.rebelosDelete(pektis);
	if (trapeziPrev) trapeziPrev.theatisDelete(pektis);

	thesi = trapezi.thesiPekti(pektis);
	if (thesi) {
		sinedria.setPektis(kodikos, thesi);
	}
	else {
		thesi = trapezi.protasiThesis(pektis);
		sinedria.setTheatis(kodikos, thesi);
		trapezi.theatisAdd(new Theatis({
			pektis: pektis,
			thesi: thesi,
		}));
	}

	skiniko.kinisiAdd(new Kinisi('ET').set({
		p: pektis,
		t: kodikos,
		d: trapezi.partida,
		z: trapezi.sizitisi,
	}));
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Service.trapezi.apodoxi = function(nodereq) {
	var skiniko = nodereq.skinikoGet(), sinedria, trapezi, thesi, tablo, query;

	if (nodereq.isvoli()) return;

	trapezi = nodereq.trapeziGet();
	if (!trapezi) return nodereq.end('Απροσδιόριστο τραπέζι');

	sinedria = nodereq.sinedriaGet();
	thesi = trapezi.thesiPekti(nodereq.loginGet());
	if (!thesi) return nodereq.end('Δεν είστε παίκτης του τραπεζιού');

	if (trapezi.apodoxes(1) != geister.thesiMax) {
		nodereq.end();
		trapezi.apodoxiSet('ΝΑΙ', thesi);
		skiniko.kinisiAdd(new Kinisi('AX').set({
			p: sinedria.pektisGet(),
		}));
		return;
	}

	tablo = trapezi.tabloGet();
	switch (tablo.fasiGet()) {
	case 'ΔΙΑΠΡΑΓΜΑΤΕΥΣΗ':
	case 'ΤΕΛΟΣ':
		return DB.connection().query('START TRANSACTION', function(conn) {
			Service.trapezi.apodoxiPartida(nodereq, conn, skiniko, trapezi, sinedria, tablo);
		});
	case 'ΣΤΗΣΙΜΟ':
		return DB.connection().query('START TRANSACTION', function(conn) {
			Service.trapezi.apodoxiPexnidi(nodereq, conn, skiniko, trapezi, sinedria, tablo);
		});
	}

	nodereq.end('Απρόβλεπτη φάση');
}

Service.trapezi.apodoxiPartida = function(nodereq, conn, skiniko, trapezi, sinedria, tablo) {
	var kodikos, protos, query, partida;

	kodikos = trapezi.kodikosGet();
	protos = (trapezi.partida.length % 2) + 1;
	query = 'INSERT INTO `partida` (`trapezi`, `protos`) VALUES (' + kodikos + ', ' + protos + ')';
	conn.queryRaw(query, function(err, res) {
		if (err || (res.affectedRows != 1)) {
			conn.rollback();
			return nodereq.end('Απέτυχε η δημιουργία παρτίδας');
		}

		conn.commit();
		nodereq.end();

		partida = new Partida({
			kodikos: res.insertId,
			trapezi: kodikos,
			enarxi: globals.toraServer(),
			protos: protos,
		});

		trapezi.partidaAdd(partida).apodoxiSet('ΟΧΙ');
		tablo.replay();

		skiniko.kinisiAdd(new Kinisi('NP').set({
			k: partida.kodikos,
			t: partida.trapezi,
			p: partida.protos,
		}));
	});
}

Service.trapezi.apodoxiPexnidi = function(nodereq, conn, skiniko, trapezi, sinedria, tablo) {
	var partida, kodikos, protos, idos = 'ΕΚΚΙΝΗΣΗ', query;

	partida = trapezi.partidaGet();
	kodikos = partida.kodikosGet();
	protos = partida.protosGet();
	query = 'INSERT INTO `energia` (`partida`, `pektis`, `idos`) VALUES (' +
		kodikos + ', ' + protos + ', ' + globals.json(idos) + ')';
	conn.queryRaw(query, function(err, res) {
		if (err || (res.affectedRows != 1)) {
			conn.rollback();
			return nodereq.end('Απέτυχε η εκκίνηση της παρτίδας');
		}

		conn.commit();
		nodereq.end();

		energia = new Energia({
			kodikos: res.insertId,
			partida: kodikos,
			pektis: protos,
			idos: idos,
			pote: globals.toraServer(),
		});

		partida.energiaAdd(energia);
		tablo.replay();

		skiniko.kinisiAdd(new Kinisi('EG').set({
			e: energia.kodikos,
			t: trapezi.kodikosGet(),
			i: idos,
			p: partida.protosGet(),
		}));
	});
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Service.trapezi.ixodopa = function(nodereq) {
	var skiniko = nodereq.skinikoGet(), sinedria, trapezi, thesi;

	if (nodereq.isvoli()) return;

	trapezi = nodereq.trapeziGet();
	if (!trapezi) return nodereq.end('Απροσδιόριστο τραπέζι');

	sinedria = nodereq.sinedriaGet();
	if (sinedria.oxiPektis()) return nodereq.end('Δεν είστε παίκτης του τραπεζιού');

	thesi = sinedria.thesiGet();
	trapezi.apodoxiSet('ΟΧΙ', thesi);

	nodereq.end();
	skiniko.kinisiAdd(new Kinisi('XA').set({
		p: sinedria.pektisGet(),
	}));
}
